﻿using System;
using System.IO;
using System.Reflection;
using Microsoft.Office.Interop.Word;

namespace XD.Office
{
    /// <summary>
    /// word操作辅助类
    /// </summary>
    public class WordHelper : IDisposable
    {
        #region 字段

        private object missing = Missing.Value;
        private Application application;
        private Document document;

        #endregion

        #region 属性

        /// <summary>
        /// 段落格式
        /// </summary>
        public ParagraphFormat ParaFormat
        {
            get
            {
                return this.document.ActiveWindow.Selection.ParagraphFormat; 
            }
            set
            {
                this.document.ActiveWindow.Selection.ParagraphFormat = value; 
            }
        }

        /// <summary>
        /// 段落字体
        /// </summary>
        public Font ParaFont
        {
            get
            {
                return this.document.ActiveWindow.Selection.Font;
            }
            set
            {
                this.document.ActiveWindow.Selection.Font = value;
            }
        }

        #endregion

        #region 构造函数

        private WordHelper() { }

        public WordHelper(string wordFile, EnumWdMode mode = EnumWdMode.wdOpenOrCreate)
        {
            application = new Application();
            application.Visible = false;
            application.DisplayAlerts = WdAlertLevel.wdAlertsNone;
            document = this.OpenDocument(wordFile, mode);
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 打开文档
        /// </summary>
        /// <param name="wordFile"></param>
        /// <returns></returns>
        private Document OpenDocument(string wordFile, EnumWdMode mode)
        {
            try
            {
                if (wordFile == null || wordFile.Equals(String.Empty))
                    throw new Exception("word文件路径不能为空！");

                switch (mode)
                { 
                    case EnumWdMode.wdCreate:
                        return this.CreateDocument(wordFile);
                    case EnumWdMode.wdOpen:
                        return this.OpenDocument(wordFile);
                    case EnumWdMode.wdOpenOrCreate:
                        if (File.Exists(wordFile))
                            return this.OpenDocument(wordFile);
                        else
                            return this.CreateDocument(wordFile);
                    default:
                        throw new NotImplementedException();
                }
            }
            catch
            {
                throw new Exception("打开或创建word文档失败！");
            }
        }
        
        /// <summary>
        /// 打开word文档
        /// </summary>
        /// <param name="wordFile"></param>
        /// <returns></returns>
        private Document OpenDocument(string wordFile)
        {
            object fileName = (object)wordFile;
            object confirmConversions = false;//允许转换
            object readOnly = false;          //只读
            object addToRecentFiles = false;  //添加到最近打开的文档
            object visible = true;

            return this.application.Documents.Open(
                ref fileName,
                ref confirmConversions,
                ref readOnly,
                ref addToRecentFiles,
                ref missing,
                ref missing,
                ref missing,
                ref missing,
                ref missing,
                ref missing,
                ref missing,
                ref visible,
                ref missing,
                ref missing,
                ref missing,
                ref missing);
        }

        /// <summary>
        /// 新建word文档
        /// </summary>
        /// <param name="wordFile"></param>
        /// <returns></returns>
        private Document CreateDocument(string wordFile)
        {
            Document doc = this.application.Documents.Add(missing, missing, missing, missing);
            object fileName = (object)wordFile;
            doc.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing, ref missing, ref missing);
            return doc;
        }

        #endregion
                
        #region 公共方法

        #region 文本操作

        /// <summary>
        /// 在当前位置插入文本
        /// </summary>
        /// <param name="text"></param>
        public void InsertText(string text)
        {
            this.document.ActiveWindow.Selection.TypeText(text);
        }

        /// <summary>
        /// 回车换行
        /// </summary>
        public void Enter()
        {
            this.document.ActiveWindow.Selection.TypeParagraph();
        }

        /// <summary>
        /// 删除插入点前面的字符
        /// </summary>
        public void DeletePreChar()
        {            
            this.document.ActiveWindow.Selection.TypeBackspace();
        }

        /// <summary>
        /// 删除文本
        /// </summary>
        /// <param name="count"></param>
        public void DeleteText(int count)
        {
            object wUnit = (object)WdUnits.wdCharacter;
            object charCount = count;
            this.document.ActiveWindow.Selection.Delete(ref wUnit, ref charCount);
        }

        /// <summary>
        /// 删除文本
        /// </summary>
        /// <param name="delStr"></param>
        public void DeleteText(string delStr)
        {
            this.ReplaceText(delStr, String.Empty);
        }

        /// <summary>
        /// 替换文本
        /// </summary>
        /// <param name="replaceText"></param>
        /// <param name="text"></param>
        public void ReplaceText(string replaceText, string text)
        {
            object replaceOption = WdReplace.wdReplaceAll;
            object oldStr = replaceText;
            object matchCase = (object)false;
            object value = text;
            this.document.Content.Find.ClearFormatting();
            this.document.Content.Find.Execute(ref oldStr, ref matchCase, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
                ref value, ref replaceOption, ref missing, ref missing, ref missing, ref missing);
        }

        /// <summary>
        /// 读取指定段落的文本内容
        /// </summary>
        /// <param name="i">指定段落的索引</param>
        /// <returns>指定段落的文本</returns>
        public string ReadParagraph(int i)
        {
            return this.document.Paragraphs[i].Range.Text.Trim();
        }

        /// <summary>
        /// 在指定书签处插入文本
        /// </summary>
        /// <param name="bookmark"></param>
        /// <param name="value"></param>
        public void InsertText(string bookmark, string value)
        {
            object bkObj = bookmark;
            if (this.document.Bookmarks.Exists(bookmark))
            {
                this.document.Bookmarks.get_Item(ref bkObj).Select();
                this.application.Selection.TypeText(value);
            }
        } 

        #endregion

        #region 表格操作

        /// <summary>
        /// 获取表格数
        /// </summary>
        /// <returns></returns>
        public int GetTableCount()
        {
            return this.document.Tables.Count;
        }

        /// <summary>
        /// 创建表格
        /// </summary>
        /// <param name="row"></param>
        /// <param name="column"></param>
        public void InsertTable(int row, int column)
        {
            Table table = this.document.Tables.Add(
                this.document.ActiveWindow.Selection.Range,
                row, column, ref missing, ref missing);
            table.Borders.OutsideLineStyle = WdLineStyle.wdLineStyleSingle;
            table.Borders.InsideLineStyle = WdLineStyle.wdLineStyleSingle;
            table.Range.Cells.VerticalAlignment = WdCellVerticalAlignment.wdCellAlignVerticalCenter;
            table.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
        }

        /// <summary>
        /// 设置表格的外边线型
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="lineStyle"></param>
        public void SetTableOutsideLineStyle(int tableIndex, EnumWdLineStyle lineStyle)
        {
            Table table = this.document.Tables[tableIndex];
            table.Borders.OutsideLineStyle = (WdLineStyle)lineStyle;
        }

        /// <summary>
        /// 设置表格的外边线宽
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="width"></param>
        public void SetTableOutsideLineWidth(int tableIndex, EnumWdLineWidth width)
        {
            Table table = this.document.Tables[tableIndex];
            table.Borders.OutsideLineWidth = (WdLineWidth)width;
        }

        /// <summary>
        /// 设置表格的外边颜色
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="color"></param>
        public void SetTableOutsideColor(int tableIndex, EnumWdColor color)
        {
            Table table = this.document.Tables[tableIndex];
            table.Borders.OutsideColor = (WdColor)color;
        }

        /// <summary>
        /// 设置表格的内边线型
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="lineStyle"></param>
        public void SetTableInsideLineStyle(int tableIndex, EnumWdLineStyle lineStyle)
        {
            Table table = this.document.Tables[tableIndex];
            table.Borders.InsideLineStyle = (WdLineStyle)lineStyle;
        }

        /// <summary>
        /// 设置表格的内边线宽
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="width"></param>
        public void SetTableInsideLineWidth(int tableIndex, EnumWdLineWidth width)
        {
            Table table = this.document.Tables[tableIndex];
            table.Borders.InsideLineWidth = (WdLineWidth)width;
        }

        /// <summary>
        /// 设置表格的内边颜色
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="color"></param>
        public void SetTableInsideColor(int tableIndex, EnumWdColor color)
        {
            Table table = this.document.Tables[tableIndex];
            table.Borders.InsideColor = (WdColor)color;
        }

        /// <summary>
        /// 设置表格中单元格的纵向排列位置
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="cellVerticalAlignment"></param>
        public void SetTableCellVerticalAlignment(int tableIndex, EnumWdCellVerticalAlignment cellVerticalAlignment)
        {
            Table table = this.document.Tables[tableIndex];
            table.Range.Cells.VerticalAlignment = (WdCellVerticalAlignment)cellVerticalAlignment;
        }

        /// <summary>
        /// 设置表格中单元格的横向排列位置
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="cellVerticalAlignment"></param>
        public void SetTableCellAlignment(int tableIndex, int row, int column, EnumWdParagraphAlignment paragraphAlignment)
        {
            Table table = this.document.Tables[tableIndex];
            table.Cell(row, column).Range.ParagraphFormat.Alignment = (WdParagraphAlignment)paragraphAlignment;
        }

        /// <summary>
        /// 设置表格的横向排列位置
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="paragraphAlignment"></param>
        public void SetTableParagraphFormatAlignment(int tableIndex, EnumWdParagraphAlignment paragraphAlignment)
        {
            Table table = this.document.Tables[tableIndex];
            table.Range.ParagraphFormat.Alignment = (WdParagraphAlignment)paragraphAlignment;
        }

        /// <summary>
        /// 合并单元格
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="beginRow"></param>
        /// <param name="beginColumn"></param>
        /// <param name="endRow"></param>
        /// <param name="endColumn"></param>
        public void MergeTableCell(int tableIndex, int beginRow, int beginColumn, int endRow, int endColumn)
        {
            if (beginRow == endRow && beginColumn == endColumn)
                return;
            Table table = this.document.Tables[tableIndex];
            table.Cell(beginRow, beginColumn).Merge(table.Cell(endRow, endColumn));
        }

        /// <summary>
        /// 拆分单元格
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <param name="splitRow"></param>
        /// <param name="splitColumn"></param>
        public void SplitTableCell(int tableIndex, int row, int column, int splitRow, int splitColumn)
        {
            object rownum = splitRow;
            object columnnum = splitColumn;
            Table table = this.document.Tables[tableIndex];
            table.Cell(row, column).Split(ref rownum, ref  columnnum);
        }

        /// <summary>
        /// 选择单元格
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        public void SelectTableCell(int tableIndex, int row, int column)
        {
            this.document.Tables[tableIndex].Cell(row, column).Select();
        }

        /// <summary>
        /// 填充单元格
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <param name="value"></param>
        public void FillTableCell(int tableIndex, int row, int column, string value)
        {
            this.SelectTableCell(tableIndex, row, column);
            this.InsertText(value);
        }

        /// <summary>
        /// 填充单元格
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <param name="moveChar"></param>
        /// <param name="value"></param>
        public void FillTableCell(int tableIndex, int row, int column, int moveChar, string value)
        {
            this.SelectTableCell(tableIndex, row, column);//选中单元格
            this.MoveEnd();//移动到单元格的末尾
            this.MoveLeftChar(moveChar);//向前移动指定的字符数
            this.InsertText(value);//填充            
        }

        /// <summary>
        /// 删除指定单元格的值
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        public void DeleteTableValue(int tableIndex, int row, int column)
        {
            this.SelectTableCell(tableIndex, row, column);
            string value = this.document.Tables[tableIndex].Cell(row, column).Range.Text.ToString();
            if (value != null && !value.Equals(String.Empty))
            {
                this.MoveHome();
                if (value.Substring(value.Length - 2, 2) == "\r\a")
                    DeleteText(value.Length - 2);
                else
                    DeleteText(value.Length);
            }
        }

        /// <summary>
        /// 读取指定表格指定单元格的文本内容
        /// </summary>
        /// <param name="tableIndex">表格索引</param>
        /// <param name="row">行索引</param>
        /// <param name="column">列索引</param>
        /// <returns>单元格的文本内容</returns>
        public string ReadTableText(int tableIndex, int row, int column)
        {
            string str = this.document.Tables[tableIndex].Cell(row, column).Range.Text;
            if (str.Substring(str.Length - 2, 2) == "\r\a")
            {
                return str.Substring(0, str.Length - 2);
            }
            return str;
        }

        /// <summary>
        /// 设置表格的列宽
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="column"></param>
        /// <param name="width"></param>
        public void SetColumnWidth(int tableIndex, int column, float width)
        {
            Table table = this.document.Tables[tableIndex];
            table.Columns[column].Width = width;
        }

        /// <summary>
        /// 设置表格的行高
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="row"></param>
        /// <param name="height"></param>
        public void SetRowHeight(int tableIndex, int row, float height)
        {
            Table table = this.document.Tables[tableIndex];
            table.Rows[row].Height = height;
        }

        /// <summary>
        /// 设置表格的行高
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="row"></param>
        /// <param name="height"></param>
        public void SetRowsHeight(int tableIndex, float height)
        {
            Table table = this.document.Tables[tableIndex];
            table.Rows.Height = height;
        }

        /// <summary>
        /// 添加列
        /// </summary>
        /// <param name="tableIndex"></param>
        public void AddColumn(int tableIndex)
        {
            Table table = this.document.Tables[tableIndex];
            table.Columns.Add(ref missing);
        }

        /// <summary>
        /// 添加行
        /// </summary>
        /// <param name="tableIndex"></param>
        public void AddRow(int tableIndex)
        {
            Table table = this.document.Tables[tableIndex];
            table.Rows.Add(ref missing);
        }
        
        #endregion

        #region 光标移动

        /// <summary>
        /// 移动到行尾
        /// </summary>
        public void MoveEnd()
        {
            object wUnit = (object)WdUnits.wdLine;
            this.document.ActiveWindow.Selection.EndKey(ref wUnit, ref missing);
        }

        /// <summary>
        /// 移动到行首
        /// </summary>
        public void MoveHome()
        {
            object wUnit = (object)WdUnits.wdLine;
            this.document.ActiveWindow.Selection.HomeKey(ref wUnit, ref missing);
        }
        
        /// <summary>
        /// 上移动指定的行数
        /// </summary>
        /// <param name="count"></param>
        public void MoveUp(int count)
        {
            object opCount = count;
            object wUnit = (object)WdUnits.wdLine;
            this.document.ActiveWindow.Selection.MoveUp(ref wUnit, ref opCount, ref missing);
        }

        /// <summary>
        /// 下移指定的行数
        /// </summary>
        /// <param name="count"></param>
        public void MoveDown(int count)
        {
            object opCount = count;
            object wUnit = (object)WdUnits.wdLine;
            this.document.ActiveWindow.Selection.MoveDown(ref wUnit, ref opCount, ref missing);
        }

        /// <summary>
        /// 左移指定的字符数
        /// </summary>
        /// <param name="leftMoveCount"></param>
        public void MoveLeftChar(int leftMoveCount)
        {
            object wUnit = (object)WdUnits.wdCharacter;
            object opCount = leftMoveCount;
            this.document.ActiveWindow.Selection.MoveLeft(ref wUnit, ref opCount, ref missing);
        }

        /// <summary>
        /// 右移指定的字符数
        /// </summary>
        /// <param name="rightMoveCount"></param>
        public void MoveRightChar(int rightMoveCount)
        {
            object wUnit = (object)WdUnits.wdCharacter;
            object opCount = rightMoveCount;
            this.document.ActiveWindow.Selection.MoveRight(ref wUnit, ref opCount, ref missing);
        }

        /// <summary>
        /// 移动到指定书签位置
        /// </summary>
        public void MoveBookmark(string bookmark)
        {
            object bkObj = bookmark;
            this.document.Bookmarks.get_Item(ref bkObj).Select();
        }

        #endregion

        #region 图片操作

        /// <summary>
        /// 插入图片
        /// </summary>
        /// <param name="imageFile"></param>
        public void InsertPicture(string imageFile)
        {
            this.document.ActiveWindow.Selection.InlineShapes.AddPicture(imageFile, ref missing, ref missing, ref missing);
        }

        /// <summary>
        /// 设置图片大小
        /// </summary>
        /// <param name="imageIndex"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void SetImageSize(int imageIndex, float width, float height)
        {            
            this.document.InlineShapes[imageIndex].Width = width;
            this.document.InlineShapes[imageIndex].Height = height;
        }

        /// <summary>
        /// 设置图片大小
        /// </summary>
        /// <param name="tableIndex"></param>
        /// <param name="imageIndex"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void SetImageSize(int tableIndex, int imageIndex, float width, float height)
        {
            this.document.Tables[tableIndex].Select();
            this.document.ActiveWindow.Selection.InlineShapes[imageIndex].Width = width;
            this.document.ActiveWindow.Selection.InlineShapes[imageIndex].Height = height;
        }

        /// <summary>
        /// 替换文本为图片
        /// </summary>
        /// <param name="replaceText"></param>
        /// <param name="imageFile"></param>
        public void ReplaceImage(string replaceText, string imageFile)
        {
            object replaceOption = WdReplace.wdReplaceAll;
            object oldStr = replaceText;
            object matchCase = (object)false;
            object value = imageFile;
            this.document.Content.Find.ClearFormatting();
            if (System.IO.File.Exists(imageFile))
            {
                this.document.Application.Selection.Find.Text = (string)oldStr;
                while (this.document.Application.Selection.Find.Execute(ref missing, ref matchCase, ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing))
                {
                    Range range = this.document.Application.Selection.Next(ref missing, ref missing);
                    if (range != null)
                    {
                        //删除文本
                        this.DeleteText(replaceText.Length - 2);
                        //插入图片
                        range.InlineShapes.AddPicture(imageFile, ref missing, ref missing, ref missing);
                    }
                }
            }
            else
            {
                value = (object)(String.Empty);
                this.document.Content.Find.Execute(ref oldStr, ref matchCase, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
                    ref value, ref replaceOption, ref missing, ref missing, ref missing, ref missing);
            }
        }

        /// <summary>
        /// 读取选中区域的第一张图片
        /// </summary>
        /// <returns>bitmap对象</returns>
        public System.Drawing.Bitmap ReadPicture()
        {
            System.Drawing.Bitmap bmp = null;
            if (this.document.ActiveWindow.Selection.InlineShapes.Count > 0)
            {
                foreach (InlineShape shape in this.document.ActiveWindow.Selection.InlineShapes)
                {
                    if (shape.Type == WdInlineShapeType.wdInlineShapePicture)
                    {
                        //获取Word中的图片
                        byte[] img = (byte[])shape.Range.EnhMetaFileBits;
                        bmp = new System.Drawing.Bitmap(new MemoryStream(img));
                        break;
                    }
                }
            }
            return bmp;
        }

        /// <summary>
        /// 读取指定图片
        /// </summary>
        /// <param name="imageIndex">图片索引</param>
        /// <returns>bitmap对象</returns>
        public System.Drawing.Bitmap ReadPicture(int imageIndex)
        {
            System.Drawing.Bitmap bmp = null;
            InlineShape shape = this.document.InlineShapes[imageIndex];
            if (shape != null && shape.Type == WdInlineShapeType.wdInlineShapePicture)
            {
                //获取Word中的图片
                byte[] img = (byte[])shape.Range.EnhMetaFileBits;
                bmp = new System.Drawing.Bitmap(new MemoryStream(img));
            }            
            return bmp;
        }

        /// <summary>
        /// 将选定区域中的第一张图片导出到指定的路径
        /// </summary>
        /// <param name="fileName">图片保存的文件名（路径+文件名）</param>
        public void ExportPicture(string fileName)
        {
            if (this.document.ActiveWindow.Selection.InlineShapes.Count > 0)
            {
                foreach (InlineShape shape in this.document.ActiveWindow.Selection.InlineShapes)
                {
                    //判断类型
                    if (shape.Type == WdInlineShapeType.wdInlineShapePicture)
                    {
                        //利用剪贴板保存数据
                        shape.Select(); //选定当前图片
                        this.document.Application.Selection.Copy();//copy当前图片
                        if (System.Windows.Forms.Clipboard.ContainsImage())
                        {
                            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(System.Windows.Forms.Clipboard.GetImage());
                            bmp.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
                            break;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 导出指定图片
        /// </summary>
        /// <param name="fileName">图片保存的文件名（路径+文件名）</param>
        /// <param name="imageIndex">图片索引</param>
        public void ExportPicture(string fileName, int imageIndex)
        {
            InlineShape shape = this.document.InlineShapes[imageIndex];
            if (shape != null && shape.Type == WdInlineShapeType.wdInlineShapePicture)
            {
                //利用剪贴板保存数据
                shape.Select(); //选定当前图片
                this.document.Application.Selection.Copy();//copy当前图片
                if (System.Windows.Forms.Clipboard.ContainsImage())
                {
                    System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(System.Windows.Forms.Clipboard.GetImage());
                    bmp.Save(fileName, System.Drawing.Imaging.ImageFormat.Png);
                }
            }            
        }

        /// <summary>
        /// 设置图片的四周环绕型
        /// </summary>
        /// <param name="imageIndex"></param>
        /// <param name="wdWrapType"></param>
        public void SetShapeWrapType(int imageIndex, EnumWdWrapType wdWrapType)
        {
            InlineShape inlineShape = this.document.InlineShapes[imageIndex];
            if (inlineShape != null)
            {
                Shape shape = inlineShape.ConvertToShape();
                shape.WrapFormat.Type = (WdWrapType)wdWrapType;
            }
        }

        #endregion

        #region 页眉

        /// <summary>
        /// 添加页眉
        /// </summary>
        /// <param name="HeaderText"></param>
        public void AddSimpleHeader(string HeaderText, 
            EnumWdParagraphAlignment wdAlign = EnumWdParagraphAlignment.wdAlignParagraphLeft)
        {   
            this.document.ActiveWindow.View.Type = WdViewType.wdOutlineView;
            this.document.ActiveWindow.View.SeekView = WdSeekView.wdSeekPrimaryHeader;
            this.document.ActiveWindow.ActivePane.Selection.InsertAfter(HeaderText);
            this.document.ActiveWindow.Selection.ParagraphFormat.Alignment = (WdParagraphAlignment)wdAlign;
            this.document.ActiveWindow.View.SeekView = WdSeekView.wdSeekMainDocument;   
        }   

        #endregion

        #region chart

        /// <summary>
        /// 插入图表
        /// </summary>
        /// <param name="bookmark"></param>
        /// <param name="data"></param>
        public void AddSimpleChart(string bookmark, string[,] data)
        {
            //插入chart
            object oClassType = "MSGraph.Chart.8";
            object bkObj = bookmark;
            Range range = this.document.Bookmarks.get_Item(ref bkObj).Range;
            InlineShape oShape = range.InlineShapes.AddOLEObject(ref oClassType, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing, ref missing);
            //Demonstrate use of late bound oChart and oChartApp objects to
            //manipulate the chart object with MSGraph.
            object oChart = oShape.OLEFormat.Object;
            object oChartApp = oChart.GetType().InvokeMember("Application", BindingFlags.GetProperty, null, oChart, null);
            //Change the chart type to Line. 
            object[] Parameters = new Object[1];
            Parameters[0] = 4; //xlLine = 4
            oChart.GetType().InvokeMember("ChartType", BindingFlags.SetProperty,
                null, oChart, Parameters);
            Chart objChart = (Chart)oShape.OLEFormat.Object;
            objChart.ChartType = Microsoft.Office.Core.XlChartType.xlColumnClustered;
            //绑定数据
            Microsoft.Office.Interop.Graph.DataSheet dataSheet = objChart.Application.DataSheet;
            int rownum = data.GetLength(0);
            int columnnum = data.GetLength(1);
            for (int i = 1; i <= rownum; i++)
                for (int j = 1; j <= columnnum; j++)
                {
                    dataSheet.Cells[i, j] = data[i - 1, j - 1];
                }
            objChart.Application.Update();
            oChartApp.GetType().InvokeMember("Update",
                BindingFlags.InvokeMethod, null, oChartApp, null);
            oChartApp.GetType().InvokeMember("Quit",
                BindingFlags.InvokeMethod, null, oChartApp, null);
            //设置大小   
            oShape.Width = this.application.InchesToPoints(6.25f);
            oShape.Height = this.application.InchesToPoints(3.57f);
        }

        #endregion

        #region 保存

        /// <summary>
        /// 保存
        /// </summary>
        public void Save()
        {
            this.document.Save();
        }

        /// <summary>
        /// 另存
        /// </summary>
        public void SaveAs(string saveFileName)
        {
            object fileName = (object)saveFileName;
            this.document.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing, ref missing, ref missing, ref missing,
                ref missing, ref missing, ref missing, ref missing, ref missing);
        }

        #endregion   

        #endregion

        #region 静态方法

        /// <summary>
        /// 杀掉word进程
        /// </summary>
        public static void KillWinWordProcess()
        {
            System.Diagnostics.Process[] processes = System.Diagnostics.Process.GetProcessesByName("WINWORD");
            foreach (System.Diagnostics.Process process in processes)
            {
                if (process.MainWindowTitle.Equals(String.Empty))
                    process.Kill();
            }
        }

        #endregion

        #region IDisposable 成员

        public void Dispose()
        {
            if (application != null)
            {
                //避免弹出normal.dot被使用的对话框   
                application.NormalTemplate.Saved = true;
            }
            if (document != null)
            {
                document.Close(ref missing, ref missing, ref missing);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(document);
                document = null;
            }
            if (application != null)
            {
                application.Application.Quit(ref missing, ref missing, ref missing);
                System.Runtime.InteropServices.Marshal.ReleaseComObject(application);
                application = null;
            }

            GC.Collect();
        }

        #endregion
    }
}
